home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
formats
/
ps16form
/
modload.asm
< prev
next >
Wrap
Assembly Source File
|
1993-04-26
|
20KB
|
489 lines
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
struc SampleRec
sname db 16h dup (?)
length dw ?
volume dw ?
repeat dw ?
replen dw ?
ends SampleRec
struc Header
songname db 20 dup (?)
samples db 31*size SampleRec dup (?)
songlen db ?
restart db ?
sequences db 128 dup (?)
mk dd ?
ends Header
ModHeader dw 0 ;; Segment of MOD Header
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
SigCopy db 'PS16■'
PS16 PS16Header <>
HeaderSeg dw 0
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_Open - MOD conversion routine. Assumes you know the file is a .MOD.
; In : CX:DX - Input MOD filename.
; BX:SI - Output PS16 filename.
; AX - Memory segment(s) to do conversion (at least 64k).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
ModIn dw 0 ;; MOD input handle.
ModOut dw 0 ;; PS16 output handle.
ModTOD dw 0 ;; Top of data.
proc MOD_Convert near
push ds es
mov [cs:ModTOD],ax
; ▒▒▒▒▒ Open/create files.
mov ds,cx ;; Open input MOD.
mov ax,3D00h
int 21h
jb @@Exit
mov [cs:ModIn],ax
mov ds,bx ;; Create output PS16.
mov dx,si
mov cx,0
mov ah,3Ch
int 21h
mov [cs:ModOut],ax
; ▒▒▒▒▒ Read and convert module.
mov ax,cs
mov ds,ax
mov es,ax
call MOD_ReadConvert
; ▒▒▒▒▒ Close files.
mov ah,3Eh ;; Close module
mov bx,[cs:ModIn]
int 21h
mov ah,3Eh ;; Close PS16
mov bx,[cs:ModOut]
int 21h
@@Exit: pop es ds
ret
endp MOD_Convert
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_ReadConvert - Conversion routine. Must be called by MOD_Open.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
proc MOD_ReadConvert near
; ▒▒▒▒▒ Read module header.
mov ax,[cs:ModTOD]
mov [cs:HeaderSeg],ax
add [cs:ModTOD],size Header/16+1
mov ds,ax
mov es,ax
mov ax,3F00h
mov bx,[cs:ModIn]
xor dx,dx
mov cx,size Header
int 21h
; ▒▒▒▒▒ Test for 15 or 31 instrument module.
cmp [Word ds:Header.mk],'.M'
jnz @@CheckFLT4
cmp [Word ds:2+Header.mk],'.K'
jz @@31Ins
@@CheckFLT4: cmp [Word ds:Header.mk],'LF'
jnz @@15Ins
cmp [Word ds:2+Header.mk],'4T'
jz @@31Ins
@@15Ins: ; ▒▒▒▒▒ Do 15 instrument conversion to 31 instrument.
mov si,20+15*30 ;; Copy orders, etc.
mov di,(offset (Header).songlen)
mov cx,134
rep movsb
mov di,offset Header+20+15*30 ;; Clear out 16-31 ins.
mov cx,16*30
mov al,0
rep stosb
mov ax,4200h ;; Reposition file ptr.
mov bx,[cs:ModIn]
mov cx,0
mov dx,258h
int 21h
@@31Ins: ; ▒▒▒▒▒ Convert 31 instrument header to PS16.
call MOD_ConvertHeader
; ▒▒▒▒▒ Convert all patterns to PS16 format.
call MOD_LoadSavePatterns
; ▒▒▒▒▒ Convert all samples to PS16 format.
call MOD_LoadSaveSamples
; ▒▒▒▒▒ Convert all instrument names to PS16 format.
call MOD_ConvertComments
; ▒▒▒▒▒ Write final header out.
mov ax,4200h
mov bx,[cs:ModOut]
mov cx,0
mov dx,0
int 21h
mov ax,cs
mov ds,ax
mov cx,size PS16Header
mov dx,offset PS16
mov ah,40h
int 21h
ret
endp MOD_ReadConvert
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_ConvertHeader - Converts the module header to a PS16 header. Called
; from MOD_ReadConvert.
; In : DS - set to segment of module header.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
proc MOD_ConvertHeader near
pusha
push ds
; ▒▒▒▒▒ Clear out PS16 Header Data.
mov ax,cs
mov es,ax
mov di,offset PS16
mov al,0
mov cx,size PS16Header
rep stosb
; ▒▒▒▒▒ Copy Sig and Name to PS16 Header.
mov di,offset PS16
mov ax,[Word cs:SigCopy]
stosw
mov ax,[Word cs:SigCopy+2]
stosw
mov al,[Byte cs:SigCopy+4]
stosb
mov si,(offset (Header).songname)
mov di,offset PS16.SongName
mov cx,20
rep movsb
mov al,26 ;; ^Z terminate it.
stosb
; ▒▒▒▒▒ Copy Song Length and Sequences to PS16Header.
mov al,[ds:Header.songlen]
mov [es:PS16.SongLen],al
mov si,(offset (Header).sequences)
mov di,offset PS16.Sequences
mov cx,128
xor ax,ax
@@SetBlock: mov ah,al
jmp @@BotLoop
@@SearchLoop: lodsb
stosb
cmp al,ah
jg @@SetBlock
@@BotLoop: loop @@SearchLoop
mov al,ah
inc al
mov [es:PS16.numpatterns],al
; ▒▒▒▒▒ Copy Samples to PS16Header doing any appropriate
; ▒▒▒▒▒ fixups as necessary.
mov bp,31 ;; 31 instruments.
mov si,(offset (Header).samples)+(offset (SampleRec).length)
mov di,offset PS16.Samples
@@FlipLoop: mov ax,[ds:si+4] ;; Get repeat start.
xchg ah,al ;; Amiga swap.
mov cx,ax ;; Save.
mov bx,[ds:si+6] ;; Get repeat length.
xchg bh,bl ;; Amiga swap.
add ax,bx ;; Add onto repeat.
mov dx,[ds:si] ;; Get the length.
xchg dh,dl ;; Amiga swap.
cmp ax,dx ;; If the repeat+replen > length...
jbe @@OKRepeat
shr cx,1 ;; Then divide the repeat by 2.
@@OKRepeat: shl dx,1 ;; Multiply the length by 2.
mov [Word es:di+PS16Sample.length],dx ;; Store it.
mov ax,[ds:si+2] ;; Get the volume and finetune and
xchg ah,al ;; swap.
mov [Word es:di+PS16Sample.volume],ax ;; Store.
shl bx,1 ;; Multiply the rep len by 2.
cmp bx,2 ;; If the repeat is <= 2,
ja @@StoreIt
mov bx,0 ;; then there isn't one.
@@StoreIt:
mov [Word es:di+PS16Sample.replen],bx ;; Store it.
shl cx,1 ;; Multiply the repeat by 2.
mov [Word es:di+PS16Sample.repeat],cx ;; Store it.
mov [Word es:di+PS16Sample.c2freq],8448 ;; C-2 Frequency.
@@OKSample: add si,size SampleRec ;; Go to next MOD sample.
add di,size PS16Sample ;; Go to next PS16 sample.
dec bp ;; T minus bp samples.
jne @@FlipLoop ;; Continue if not done.
; ▒▒▒▒▒ Write PS16 Header to file.
mov bx,[cs:ModOut]
mov ax,cs
mov ds,ax
mov cx,size PS16Header
mov dx,offset PS16
mov ah,40h
int 21h
pop ds
popa
ret
endp MOD_ConvertHeader
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_LoadSavePatterns - Converts MOD patterns to PS16 patterns and saves
; them to disk.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
ModPatSeg dw 0
ModBuf3 dw 0
LastLine db 0FFh
proc MOD_LoadSavePatterns near
; ▒▒▒▒▒ Allocate buffers.
mov ax,[cs:ModTOD]
mov [cs:ModPatSeg],ax ;; 1k MOD pattern buffer.
add ax,1024/16
mov [cs:ModBuf3],ax ;; 3K PS16 pattern buffer.
mov es,ax
mov [cs:LastLine],0FFh
; ▒▒▒▒▒ Start loop.
mov cx,0
@@BlockReadLoop:; ▒▒▒▒▒ Read in a pattern.
push cx
mov cx,1024
mov bx,[cs:ModIn]
mov ax,[cs:ModPatSeg]
mov ds,ax
xor dx,dx
mov ax,3F00h ; Load in the block.
int 21h
; ▒▒▒▒▒ Set up for compression.
mov ax,[cs:ModBuf3] ; Clear pattern of garbage.
mov es,ax
mov di,0
mov cx,3072/2
mov ax,0
rep stosw
mov di,0
mov ax,0 ; Size of pattern so far.
stosw
mov al,64 ; Number of lines in pattern.
stosb
mov cx,0 ; CX - Number of Channels Done.
@@ChannelLoop: ; ▒▒▒▒▒ Compress this baby!
push cx ; Push Number of Channels Done.
shl cx,2 ; MOD channel offset - Channel*4.
mov si,cx
mov cx,0 ; Current line counter (0-63)
@@LineLoop: push cx
cmp [Word ds:si],0 ; Is there anything at all to
jne @@ItsThere ; compress?
cmp [Word ds:si+2],0
je @@NothingSkip ; No! Skip compressing this line.
@@ItsThere: xor dh,dh
mov dl,cl
dec dl
cmp [cs:LastLine],dl
jne @@WholeLineStore
mov dh,10000000b
jmp @@SkipLineStore
@@WholeLineStore:
mov al,cl ; Store down the current line.
stosb
@@SkipLineStore:mov [cs:LastLine],cl
call MOD_NoteMatcher ; Find a matching note.
mov bl,[ds:si] ; Get the hi byte of instrument.
and bl,0F0h
shl bl,2 ; Shift it so it will fit in our note.
or al,bl ; Put 'em together.
or al,dh ; Put on whether line is continuous.
stosb ; ...and store it down.
mov ax,[ds:si+2] ; Also store the lo byte of ins.
stosw ; and the special effect and data.
@@NothingSkip: add si,16 ; Go to next MOD pattern line.
pop cx ; Pop off the line counter.
inc cx
cmp cx,64 ; Are we done?
jne @@LineLoop
mov al,-1 ; Store a -1 to signify End of Track.
stosb
pop cx ; Pop off the Channel Counter.
inc cx ; Since MODs are only four channels,
cmp cx,4 ; we only have four channels to
jnz @@ChannelLoop ; do.
; ▒▒▒▒▒ Store channels 4-16 as -1's.
mov cx,4 ; Channel Counter.
@@CLoop: mov al,-1
stosb
inc cx
cmp cx,16
jnz @@CLoop
; ▒▒▒▒▒ Store the new PS16 pattern size in position 0.
mov bx,di ; Save size.
mov cx,bx ; Modify it to 16-byte bound.
and cx,0Fh ; Are lower 4 bits set to anything?
or cx,cx
je @@OKSize
and bx,0FFF0h
add bx,16
@@OKSize: add [Word cs:PS16.totalPatternSize],bx
adc [Word cs:2+PS16.totalPatternSize],0
mov di,0
mov cx,bx ; Size for save.
mov ax,bx
stosw
; ▒▒▒▒▒ Write the PS16 pattern to disk.
mov ax,[cs:ModBuf3]
mov ds,ax
mov dx,0
mov bx,[cs:ModOut]
mov ah,40h
int 21h
; ▒▒▒▒▒ Are we done yet?
pop cx
inc cx
cmp cl,[cs:PS16.numpatterns]
jnz @@BlockReadLoop
ret
endp MOD_LoadSavePatterns
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_NoteMatcher - Tries to come up with an equivalent note position as per
; the MOD_Match table. For instance, 1712 is 1, 56 is 60
; and 0 is 0.
; In : DS:SI - MOD note.
; Out: AX - Note found (0-61)
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
MOD_Match dw 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,912
dw 856,808,762,720,678,640,604,570,538,508,480,453
dw 428,404,381,360,339,320,302,285,269,254,240,226
dw 214,202,190,180,170,160,151,143,135,127,120,113
dw 107,101,95,90,85,80,75,71,67,63,60,56,0
proc MOD_NoteMatcher near
mov ax,[ds:si] ; Get the note.
xchg ah,al ; Amiga swap.
and ax,0FFFh ; We want only the note.
or ax,ax ; Is there one?
je @@Done ; NOPE!!!
mov bx,offset MOD_Match
mov cx,0 ; Note counter.
@@NoteMatcher: cmp ax,[cs:bx] ; Do we have a close match?
jae @@Found ; YES!
add bx,2 ; Kick our pointer up by a word.
inc cx ; Increment the note counter.
cmp cx,61 ; Are we out of notes?
jnz @@NoteMatcher
mov ax,0 ; If we made it here, then the note
ret ; in question was WAY out of range.
@@Found: mov ax,cx ; Return the result.
inc ax
@@Done: ret
endp MOD_NoteMatcher
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_LoadSaveSamples - Loads and saves the new PS16 samples to disk.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
proc MOD_LoadSaveSamples near
mov cx,31
mov bx,offset PS16.Samples
@@DoSamples: push cx bx
; ▒▒▒▒▒ Is this a sample?
mov cx,[Word cs:bx+PS16Sample.length]
or cx,cx
je @@Bottom
; ▒▒▒▒▒ Load sample.
mov ds,[cs:ModTOD]
mov dx,0
mov bx,[cs:ModIn]
mov ax,3F00h
int 21h
; ▒▒▒▒▒ Convert sample.
mov es,[cs:ModTOD]
xor si,si
xor di,di
call MOD_ConvertSample
; ▒▒▒▒▒ Save sample.
mov ds,[cs:ModTOD]
mov dx,0
mov bx,[cs:ModOut]
mov ah,40h
int 21h
@@Bottom: pop bx
add bx,size PS16Sample
pop cx
loop @@DoSamples
ret
endp MOD_LoadSaveSamples
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_ConvertSample - Converts sample to new format for better compression.
; In : DS:SI - Pointer to input sample
; ES:DI - Pointer to output sample
; CX - Number of bytes to do.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
proc MOD_ConvertSample
push cx
jcxz @@20 ; Abort if nothing to do.
mov ah, 0
@@10: lodsb
mov bl, al
sub al, ah
stosb
mov ah, bl
loop @@10
@@20: pop cx
ret
endp MOD_ConvertSample
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; MOD_ConvertComments - Converts instrument names to comments.
; In : DS:SI - Pointer to input sample
; ES:DI - Pointer to output sample
; CX - Number of bytes to do.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
InsText db 'INST',22,31
proc MOD_ConvertComments
mov ax,4201h ; Get current position.
mov bx,[cs:ModOut]
xor cx,cx
xor dx,dx
int 21h
mov [Word PS16.commentofs],ax ; Store comment ofs.
mov [Word 2+PS16.commentofs],dx
mov ax,cs ; Write INST text.
mov ds,ax
mov dx,offset InsText
mov cx,6
mov ah,40h
int 21h
mov ds,[cs:HeaderSeg]
mov si,(offset (Header).samples)+(offset (SampleRec).sname)
mov cx,31
@@CopyIns: push cx
mov dx,si ; Write sample name.
mov cx,22
mov ah,40h
int 21h
add si,size SampleRec
pop cx
loop @@CopyIns
ret
endp MOD_ConvertComments